package com.dc.web.controller;


import com.dc.constant.MessageConstant;
import com.dc.dao.*;
import com.dc.entity.*;
import com.dc.exception.ServiceException;
import com.dc.model.AjaxResult;
import com.dc.model.PageListBody;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@Api(tags = "2-船体焊接")
@RestController
@RequestMapping("/api/calibration_ship_weld")
@Slf4j
public class CalibrationShipWeldController {

    @Resource
    CalibrationShipWeldDao calibrationShipWeldDao;

    @Resource
    CalibrationShipWeldChildDao calibrationShipWeldChildDao;

    @Resource
    ShipDao shipDao;

    @GetMapping("/list")
    public AjaxResult list(PageListBody body) {

        Integer pageNumber = body.getPageNumber();
        pageNumber = ObjectUtils.defaultIfNull(pageNumber, 1);
        Integer pageSize = body.getPageSize();
        pageSize = ObjectUtils.defaultIfNull(pageSize, 20);

        PageRequest pageRequest = PageRequest.of(pageNumber - 1, pageSize);

        Page<CalibrationShipWeldEntity> all = calibrationShipWeldDao.findAll(pageRequest);

        all.getContent().forEach(t-> {
            t.setShipId(t.getShip().getId());
            t.setShipName(t.getShip().getName());
        });

        return AjaxResult.success(all);
    }

    @GetMapping("/{id}")
    public AjaxResult show(@PathVariable("id") Long id) {
        Optional<CalibrationShipWeldEntity> optional = calibrationShipWeldDao.findById(id);
        CalibrationShipWeldEntity entity = null;
        if (optional.isPresent()) {
            entity = optional.get();
            entity.setShipId(entity.getShip().getId());
            entity.setShipName(entity.getShip().getName());
            return AjaxResult.success(entity);
        } else {
            return AjaxResult.error("数据不存在! id = " + id);
        }
    }

    @PostMapping()
    public AjaxResult add(@RequestBody CalibrationShipWeldEntity entity) {
        entity.setId(null);
        ShipEntity ship = shipDao.findById(entity.getShipId()).get();
        entity.setShip(ship);
        // 动态计算
        calc(entity);

        CalibrationShipWeldEntity save = calibrationShipWeldDao.save(entity);
        save.setShipName(ship.getName());
        return AjaxResult.success(save);
    }

    @PutMapping("/{id}")
    public AjaxResult update(@PathVariable("id") Long id, @RequestBody CalibrationShipWeldEntity entity) {

        Optional<CalibrationShipWeldEntity> optionalRust = calibrationShipWeldDao.findById(id);
        if(!optionalRust.isPresent()) {
            throw new ServiceException(MessageConstant.ERR_CALIBRATION_MISSION);
        }

        CalibrationShipWeldEntity rustEntity = optionalRust.get();

        if(!rustEntity.getShip().getId().equals(entity.getShipId())) {      // 如果ship有更换，则更新shipId，否则不更新shipID
            Optional<ShipEntity> optionalShip = shipDao.findById(entity.getShipId());
            if(!optionalShip.isPresent()) {
                throw new ServiceException(MessageConstant.ERR_SHIP_MISSING);
            }
            ShipEntity ship = optionalShip.get();
            rustEntity.setShip(ship);
        }

        //////////// 更新字段
        rustEntity.length = entity.length;
        rustEntity.startTime = entity.startTime;
        rustEntity.date = entity.date;
        rustEntity.endTime = entity.endTime;
        rustEntity.machineNum = entity.machineNum;
        rustEntity.startCO2 = entity.startCO2;
        rustEntity.endCO2 = entity.endCO2;
        ///////////

        /////////// 动态更新
        calc(rustEntity);
        //////////

        ShipEntity ship = rustEntity.getShip();

        CalibrationShipWeldEntity save = calibrationShipWeldDao.save(rustEntity);
        save.setShipId(ship.getId());
        save.setShipName(ship.getName());
        save.getInner().forEach(t -> t.setPid(save.getId()));

        return AjaxResult.success(save);
    }

    @DeleteMapping("/{id}")
    public AjaxResult delete(@PathVariable("id") Long id) {
        Optional<CalibrationShipWeldEntity> optional = calibrationShipWeldDao.findById(id);
        if (optional.isPresent()) {
            CalibrationShipWeldEntity entity = optional.get();
            List<CalibrationShipWeldChildEntity> inner = entity.getInner();

            if(ObjectUtils.isNotEmpty(inner)) {
                Collection<Long> collect = inner.stream().map(CalibrationShipWeldChildEntity::getId).collect(Collectors.toList());
                calibrationShipWeldChildDao.deleteAllById(collect);
            }
            calibrationShipWeldDao.deleteById(id);

        }
        return AjaxResult.success();
    }

    /////////////////////////////////////// child ////////////////////////////////////////////

    @GetMapping("/child/{id}")
    public AjaxResult showChild(@PathVariable("id") Long id) {
        Optional<CalibrationShipWeldChildEntity> optional = calibrationShipWeldChildDao.findById(id);
        CalibrationShipWeldChildEntity entity = null;
        if (optional.isPresent()) {
            entity = optional.get();
            entity.setPid(entity.getCalibrationShipWeldEntity().getId());
            return AjaxResult.success(entity);
        } else {
            return AjaxResult.error("数据不存在! id = " + id);
        }
    }

    @PostMapping("/child")
    public AjaxResult addChild(@RequestBody CalibrationShipWeldChildEntity entity) {
        entity.setId(null);
        Optional<CalibrationShipWeldEntity> optional = calibrationShipWeldDao.findById(entity.getPid());
        if(optional.isPresent()) {
            CalibrationShipWeldEntity calibrationShipWeldEntity = optional.get();
            entity.setCalibrationShipWeldEntity(calibrationShipWeldEntity);
            CalibrationShipWeldChildEntity save = calibrationShipWeldChildDao.save(entity);

            ////////////////////////////////
            // 动态计算
            calibrationShipWeldEntity.getInner().add(entity);

            calc(calibrationShipWeldEntity);

            // 查询父，进行计算
            calibrationShipWeldDao.save(calibrationShipWeldEntity);

            return AjaxResult.success(save);
        }
        return AjaxResult.error("数据不存在！! id = " + entity.getId());
    }

    @PutMapping("/child/{id}")
    public AjaxResult updateChild(@PathVariable("id") Long id, @RequestBody CalibrationShipWeldChildEntity entity) {
        entity.setId(id);
        Optional<CalibrationShipWeldEntity> optional = calibrationShipWeldDao.findById(entity.getPid());
        if(!optional.isPresent()) {
            throw new ServiceException(MessageConstant.ERR_CALIBRATION_MISSION);
        }

        CalibrationShipWeldEntity calibrationShipWeldEntity = optional.get();
        entity.setCalibrationShipWeldEntity(calibrationShipWeldEntity);
        CalibrationShipWeldChildEntity save = calibrationShipWeldChildDao.save(entity);

        ///////////////////////////////////////
        // 动态计算
        calc(calibrationShipWeldEntity);

        // 查询父，进行计算
        calibrationShipWeldDao.save(calibrationShipWeldEntity);

        save.setPid(entity.getPid());
        return AjaxResult.success(save);
    }

    @DeleteMapping("/child/{id}")
    public AjaxResult deleteChild(@PathVariable("id") Long id) {
        Optional<CalibrationShipWeldChildEntity> childEntityOptional = calibrationShipWeldChildDao.findById(id);
        if(childEntityOptional.isPresent()) {
            CalibrationShipWeldChildEntity childEntity = childEntityOptional.get();
            CalibrationShipWeldEntity calibrationPaintHouseEntity = childEntity.getCalibrationShipWeldEntity();
            calibrationPaintHouseEntity.getInner().remove(childEntity);

            // 动态计算
            calc(calibrationPaintHouseEntity);

            calibrationShipWeldDao.save(calibrationPaintHouseEntity);

            calibrationShipWeldChildDao.deleteById(id);
            return AjaxResult.success();
        } else {
            return AjaxResult.error("数据不存在！! id = " + id);
        }
    }

    private CalibrationShipWeldEntity calc(CalibrationShipWeldEntity entity) {
        // co2 = endCO2 - startCO2
        try {
            entity.co2 = entity.endCO2 - entity.startCO2;
        } catch (Exception e) {
            entity.co2 = 0.;
        }

        // co2ByUnit = co2 / length
        try {
            entity.co2ByUnit = entity.co2 / entity.length;
        } catch (Exception e) {
            entity.co2ByUnit = 0.;
        }


        // powers = 子表的  所有(endPower - startPower)
        try {
            List<CalibrationShipWeldChildEntity> inner = entity.getInner();
            Double powers = inner.stream().map(t -> {
                Double endPower = t.getEndPower() == null ? 0. : t.getEndPower();
                Double startPower = t.getStartPower() == null ? 0. : t.getStartPower();
                return (endPower - startPower);
            }).reduce(Double::sum).orElse(0.0);
            entity.powers = powers;
        } catch (Exception e) {
            entity.powers = 0.;
        }


        // powerByUnit = powers / length
        try {
            entity.powerByUnit = entity.powers / entity.length;
        } catch (Exception e) {
            entity.powerByUnit = 0.;
        }

        return entity;
    }
}
